package cn.zkteco.doordu.ui;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.AppCompatSpinner;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import cn.zkteco.doordu.R;
import cn.zkteco.doordu.adapter.CmdAdapter;
import cn.zkteco.doordu.adapter.OptionsAdapter;
import cn.zkteco.doordu.model.Cmd;
import cn.zkteco.doordu.proxy.LeProxy;
import cn.zkteco.doordu.service.BleService;
import cn.zkteco.doordu.utils.DateUtil;
import cn.zkteco.doordu.utils.DbUtils;
import cn.zkteco.doordu.utils.FileUtil;
import cn.zkteco.doordu.utils.HexAsciiWatcher;
import cn.zkteco.doordu.utils.LogUtil;
import cn.zkteco.doordu.utils.TransformUtil;

/**
 * Created by Administrator on 2017/10/11.
 */

public class ControlA extends AppCompatActivity implements AdapterView.OnItemSelectedListener, View.OnClickListener {

    private static final int REQ_HEX_INPUT = 3;
    private AppCompatSpinner spinner;
    private static final String TAG = "ControlA------>";

    public BleService bleService;
    public String name, address; //设备名和地址
    public CmdAdapter cmdAdapter;
    public List<Cmd> cmds; //存储返回命令的结果

    public ListView lvCmd;
    public Button btnSend, btnClear, btnConnect;
    public EditText etCmd;
    public RelativeLayout rlConnect;
    public TextView tvConnectStatus;
    public TextView progress;

    public int spinnerPosition = 2;
    public int value_connect = 99;//默认是握手99，连接100

    byte[] sendCMD;
    byte[] contentData; //内容数据
    byte[] header = new byte[]{(byte) 0xAA, (byte) 0xBE, 0x00, 0x00}; //

    Timer timer = new Timer();
    int sentPackages = 0;

    int packs = 0, remain = 0;
    byte[] SerializableNum = new byte[20];


    HexAsciiWatcher mInputWatcher;


    private final ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.w(TAG, "onServiceDisconnected()");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            bleService = ((BleService.LocalBinder) service).getService();
            if (!bleService.initialize()) {
                Log.e(TAG, "Unable to initialize Bluetooth");
                finish();
            }
            bleService.connect(address);
        }
    };

    private final BroadcastReceiver mLocalReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

//            String address = intent.getStringExtra(LeProxy.EXTRA_ADDRESS);
            String action = intent.getAction();
            LogUtil.v(ControlA.this, action);
            if (action.equals(LeProxy.ACTION_GATT_CONNECTED)) {
                LogUtil.v(ControlA.this, "连接成功");
            } else if (action.equals(LeProxy.ACTION_GATT_DISCONNECTED)) {
                LogUtil.v(ControlA.this, "取消连接");
            } else if (action.equals(LeProxy.ACTION_GATT_SERVICES_DISCOVERED)) {
                LogUtil.v(ControlA.this, "发现服务");

                bleService.enableNotification();
                bleService.enableRead();
                bleService.enableIndication();
            } else if (action.equals(LeProxy.AVAILABLE_DATA)) {
                final byte[] data = intent.getByteArrayExtra(LeProxy.EXTRA_DATA);
                if (value_connect == 99) {
                    if (data[3] == 0) {
                        header[3] = 0x00;
                        contentData = new byte[]{0x01};
                        header[2] = (byte) contentData.length;
                        sentByteByCommand();
                        value_connect = 100;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                tvConnectStatus.setText("设置长连接模式");
                            }
                        });
                    } else {
                        value_connect = -1;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                rlConnect.setVisibility(View.INVISIBLE);
                                Toast.makeText(ControlA.this, "连接失败", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                } else if (value_connect == 100) {
                    if (data[3] == 0) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                rlConnect.setVisibility(View.INVISIBLE);
                                Toast.makeText(ControlA.this, "连接成功", Toast.LENGTH_SHORT).show();
                            }
                        });
                        value_connect = -1;
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(ControlA.this, "设置长连接失败", Toast.LENGTH_SHORT).show();
                                rlConnect.setVisibility(View.INVISIBLE);
                            }
                        });
                        value_connect = -1;
                    }
                } else if (value_connect == 101) { //数据擦除
                    if (data[3] == 0) {
                        value_connect = 102;
                        header[3] = 0x61;
                        contentData = new byte[]{};
                        header[2] = (byte) contentData.length;
                        sentByteByCommand();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                tvConnectStatus.setText("设备复位成功");
                            }
                        });
                    } else {
                        value_connect = -1;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(ControlA.this, "升级失败,设备复位失败", Toast.LENGTH_SHORT).show();
                                rlConnect.setVisibility(View.INVISIBLE);
                            }
                        });
                    }
                } else if (value_connect == 102) { //写flash
                    if (data[3] == 0) {
                        if (packs == 0) {
                            header[3] = 0x62;
                            contentData = FileUtil.getBytesFromAssets(ControlA.this, "R515_20171122_V1.02_upgrade.bin");
                            remain = (contentData.length) % 8;
                            packs = (contentData.length) / 8;
                            if (remain > 0) {
                                packs += 1;
                            }
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    tvConnectStatus.setText("正在升级...");
                                }
                            });
                        }
                        writeFlash();
                    } else {
                        value_connect = -1;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(ControlA.this, "升级失败,数据擦除失败", Toast.LENGTH_SHORT).show();
                                rlConnect.setVisibility(View.INVISIBLE);
                            }
                        });
                    }
                } else if (value_connect == 103) {
                    if (data[3] == 0) {
                        value_connect = 104;
                        header[3] = 0x63;
//                        contentData = FileUtil.getFileMD5(ControlA.this, "R515_test.bin");
                        contentData = new byte[]{(byte) 0xfe, (byte) 0x8a, 0x0d, (byte) 0xb6, (byte) 0xd0,
                                0x39, 0x33, 0x31, (byte) 0xa6, (byte) 0xea, 0x4a, (byte) 0xce, 0x7e, 0x08, 0x02, (byte) 0xfa};
                        header[2] = 0x10;
                        sentByteByCommand();

                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                rlConnect.setVisibility(View.INVISIBLE);
                                Toast.makeText(ControlA.this, "固件写入完成", Toast.LENGTH_SHORT).show();
                            }
                        });

                    } else {
                        value_connect = -1;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(ControlA.this, "升级失败,固件写入出错", Toast.LENGTH_SHORT).show();
                                rlConnect.setVisibility(View.INVISIBLE);
                            }
                        });

                    }
                } else if (value_connect == 104) {
                    if (data[3] == 0) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(ControlA.this, "升级成功,请重新连接", Toast.LENGTH_SHORT).show();
                                rlConnect.setVisibility(View.INVISIBLE);
                                progress.setVisibility(View.INVISIBLE);
                                ControlA.this.finish();
                            }
                        });
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(ControlA.this, "升级失败,运行失败", Toast.LENGTH_SHORT).show();
                                rlConnect.setVisibility(View.INVISIBLE);
                                progress.setVisibility(View.INVISIBLE);

                            }
                        });
                        value_connect = -1;
                    }
                } else {
                    handAvaLiableData(data);
                }

            }
        }
    };


    private void writeFlash() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!progress.isShown()) {
                    progress.setVisibility(View.VISIBLE);
                }
                if (sentPackages % 10 == 0) {
                    double p = (double)sentPackages / packs;
                    progress.setText(String.format("%.2f", p*100) + " %");
                }
            }
        });
        if (sentPackages < packs) {
            byte[] data;
            if (sentPackages + 1 == packs) {
                if (remain == 0) {
                    data = new byte[8];
                    header[2] = (byte) 0x08;
                } else {
                    data = new byte[remain];
                    header[2] = (byte) remain;
                }
                value_connect = 103;
            } else {
                data = new byte[8];
                header[2] = (byte) 0x08;
            }
            for (int j = 0; j < 8; j++) {
                if (8 * sentPackages + j < contentData.length) {
                    data[j] = contentData[8 * sentPackages + j];
                }
            }
            sendCMD = byteMerger(header, data);
            bleService.sendCmd(build_cmd(sendCMD));
            sentPackages++;
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(ControlA.this, "更新完成", Toast.LENGTH_SHORT).show();
                    rlConnect.setVisibility(View.INVISIBLE);
                }
            });
            sentPackages = 0;
        }

    }


    public byte[] cutData(byte[] data) {
        byte[] dest;
        dest = new byte[data.length - 5];
        System.arraycopy(data, 4, dest, 0, dest.length);
        return dest;
    }


    public void handAvaLiableData(byte[] data) {
        String value = TransformUtil.byteArrayToString(data);
        switch (spinnerPosition) {
            case 0:
                if (data[3] == 0) {

                    cmds.add(new Cmd(value, "蓝牙系统参数设置", 0));
                } else {
                    cmds.add(new Cmd(value, "蓝牙系统参数设置", 1));
                }
                break;
            case 1:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "获取蓝牙系统参数", 0));
                } else {
                    cmds.add(new Cmd(value, "获取蓝牙系统参数", 1));
                }
                break;
            case 2:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "蓝牙开门", 0));
                } else {
                    cmds.add(new Cmd(value, "蓝牙开门", 1));
                }
                break;
            case 3:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "设置蓝牙密码", 0));
                    DbUtils.saveKey(ControlA.this, etCmd.getText().toString().trim());
                } else {
                    cmds.add(new Cmd(value, "设置蓝牙密码", 1));
                }
                break;
            case 4:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "注册设备信息", 0));
                    String k = etCmd.getText().toString().trim();
                    DbUtils.saveKey(ControlA.this, k.substring(2));
                } else {
                    cmds.add(new Cmd(value, "注册设备信息", 1));
                }
                break;
            case 5:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "注销设备信息", 0));
                    DbUtils.saveKey(ControlA.this, "FFFFFFFFFFFFFFFFFFFFFFFF");
                } else {
                    cmds.add(new Cmd(value, "注销设备信息", 1));
                }
                break;
            case 6:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.getChars(cutData(data)), "获取软件版本号", 0));
                } else {
                    cmds.add(new Cmd(value, "获取软件版本号", 1));
                }
                break;
            case 7:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.getChars(cutData(data)), "获取硬件版本号", 0));
                } else {
                    cmds.add(new Cmd(value, "获取硬件版本号", 1));
                }
                break;
            case 8:

                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "设置出厂序列号", 0));
                } else {
                    cmds.add(new Cmd(value, "设置出厂序列号", 1));
                }

                break;
            case 9:
                if (data[0] == (byte) 0xAA) {
                    SerializableNum = data;
                } else {
                    if (SerializableNum[3] == 0) {
                        byte[] tmp = byteMerger(SerializableNum, data);
                        cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(tmp)), "获取出厂序列号", 0));
                    } else {
                        cmds.add(new Cmd(value, "获取出厂序列号", 1));
                    }
                }
                break;
            case 10:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "更新设备时间", 0));
                } else {
                    cmds.add(new Cmd(value, "更新设备时间", 1));
                }
                break;
            case 11:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(data)), "获取设备时间", 0));
                } else {
                    cmds.add(new Cmd(value, "获取设备时间", 1));
                }
                break;
            case 12:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "增加黑名单", 0));
                } else {
                    cmds.add(new Cmd(value, "查询黑名单", 1));
                }
                break;
            case 13:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(data)), "查询黑名单", 0));
                } else {
                    cmds.add(new Cmd(value, "查询黑名单", 1));
                }
                break;
            case 14:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "删除黑名单", 0));
                } else {
                    cmds.add(new Cmd(value, "删除黑名单", 1));
                }
                break;
            case 15:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "清空黑名单", 0));
                } else {
                    cmds.add(new Cmd(value, "清空黑名单", 1));
                }
                break;
            case 16:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(data)), "获取黑名单总数", 0));
                } else {
                    cmds.add(new Cmd(value, "获取黑名单总数", 1));
                }
                break;
            case 17:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "增加白名单", 0));
                } else {
                    cmds.add(new Cmd(value, "增加白名单", 1));
                }
                break;
            case 18:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(data)), "查询白名单", 0));
                } else {
                    cmds.add(new Cmd(value, "查询白名单", 1));
                }
                break;
            case 19:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "删除白名单", 0));
                } else {
                    cmds.add(new Cmd(value, "删除白名单", 1));
                }
                break;
            case 20:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "清空白名单", 0));
                } else {
                    cmds.add(new Cmd(value, "清空白名单", 1));
                }
                break;
            case 21:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(data)), "获取白名单总数", 0));
                } else {
                    cmds.add(new Cmd(value, "获取白名单总数", 1));
                }
                break;
            case 22:
                if (data[3] == 0) {
                    cmds.add(new Cmd(TransformUtil.byteArrayToString(cutData(data)), "获取开门次数", 0));
                } else {
                    cmds.add(new Cmd(value, "获取开门次数", 1));
                }
                break;
            case 23:
                if (data[0] == (byte) 0xAA) {
                    SerializableNum = data;
                } else {
                    byte[] tmp = byteMerger(SerializableNum, data);
                    byte[] d = cutData(tmp);
                    if (SerializableNum[3] == 0) {
                        byte[] time = new byte[4];
                        int type = d[d.length-6];
                        System.arraycopy(d,d.length-6,time,0,4);
                        if (type==0){ //IC卡开门
                            byte[] ic = new byte[6];
                            System.arraycopy(d,0,ic,0,6);
                            cmds.add(new Cmd(TransformUtil.byteArrayToString(ic)+"  "+DateUtil.byte2date(time,10), "批量导出开门记录", 0));
                        }else if (type==3){ //按键开门
                            byte[] finger = new byte[7];
                            System.arraycopy(d,0,finger,0,7);
                            cmds.add(new Cmd(TransformUtil.byteArrayToString(finger)+"  "+DateUtil.byte2date(time,10), "批量导出开门记录", 0));
                        }else{ //蓝牙和身份证
                            byte[] other = new byte[10];
                            System.arraycopy(d,0,other,0,10);
                            cmds.add(new Cmd(TransformUtil.byteArrayToString(other)+"  "+DateUtil.byte2date(time,10), "批量导出开门记录", 0));
                        }

                    } else {

                        cmds.add(new Cmd("AABE0001BF", "批量导出开门记录", 1));
                    }
                }
                break;
            case 24:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "清空开门记录", 0));
                } else {
                    cmds.add(new Cmd(value, "清空开门记录", 1));
                }
                break;
            case 25:
                if (data[3] == 0) {
                    cmds.add(new Cmd(value, "读取外部flash", 0));
                } else {
                    cmds.add(new Cmd(value, "读取外部flash", 1));
                }
                break;
            default:
                break;
        }
        cmdAdapter.notifyDataSetChanged();
        lvCmd.setSelection(cmds.size() - 1);
    }


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_control);

        getExtras();

        initUI();

        Intent gattServiceIntent = new Intent(this, BleService.class);
        bindService(gattServiceIntent, mConnection, BIND_AUTO_CREATE);

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                sendShakeHandCommand();
            }
        }, 2000);

    }

    private void sendShakeHandCommand() {
        System.out.println("------------->开始握手");
//        DbUtils.saveKey(ControlA.this,"111111111111111111111111");
//        DbUtils.saveKey(ControlA.this,"FFFFFFFFFFFFFFFFFFFFFFFF");
        String key = DbUtils.getKey(ControlA.this);
        header[3] = 0x03;
        contentData = TransformUtil.getMD5(key);
        header[2] = (byte) contentData.length;
        sentByteByCommand();
    }

    private void initUI() {

        progress = (TextView) findViewById(R.id.tvPro);

        cmds = new ArrayList<>();
        lvCmd = (ListView) findViewById(R.id.lvCmd);

        cmdAdapter = new CmdAdapter(this, cmds);
        lvCmd.setAdapter(cmdAdapter);

        rlConnect = (RelativeLayout) findViewById(R.id.rl_connet);
        tvConnectStatus = (TextView) findViewById(R.id.tv_connect_status);

        spinner = (AppCompatSpinner) findViewById(R.id.spinner);
        spinner.setAdapter(new OptionsAdapter(this));
        spinner.setOnItemSelectedListener(this);

        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
//            getSupportActionBar().setTitle(name);
//            getSupportActionBar().setSubtitle(address);
        }

        etCmd = (EditText) findViewById(R.id.et_cmd);
        etCmd.setOnClickListener(this);


        btnSend = (Button) findViewById(R.id.btn_send);
        btnClear = (Button) findViewById(R.id.btn_clear);
        btnConnect = (Button) findViewById(R.id.btn_update);

        btnSend.setOnClickListener(this);
        btnClear.setOnClickListener(this);
        btnConnect.setOnClickListener(this);

        mInputWatcher = new HexAsciiWatcher(this);
        mInputWatcher.setHost(etCmd);
//        mInputWatcher.setIndicator(tvInputBytes);
        etCmd.addTextChangedListener(mInputWatcher);
    }

    private void getExtras() {
        Intent intent = getIntent();
        name = intent.getStringExtra(LeProxy.DEVICE_NAME);
        address = intent.getStringExtra(LeProxy.DEVICE_ADDRESS);
    }

    private void goHexInputActivity() {
        Intent intent = new Intent(this, HexInputActivity.class);
        intent.putExtra(HexInputActivity.EXTRA_MAX_LENGTH, mInputWatcher.getMaxLength());
        intent.putExtra(HexInputActivity.EXTRA_HEX_STRING, etCmd.getText().toString());
        startActivityForResult(intent, REQ_HEX_INPUT);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQ_HEX_INPUT && resultCode == Activity.RESULT_OK) {
            String hexStr = data.getStringExtra(HexInputActivity.EXTRA_HEX_STRING);
            etCmd.setText(hexStr);
            etCmd.setSelection(hexStr.length());
        }
        super.onActivityResult(requestCode, resultCode, data);
    }


    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(mLocalReceiver, makeFilter());
        if (bleService != null) {
            final boolean result = bleService.connect(address);
        }
    }

    private IntentFilter makeFilter() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(LeProxy.ACTION_GATT_CONNECTED);
        filter.addAction(LeProxy.ACTION_GATT_DISCONNECTED);
        filter.addAction(LeProxy.ACTION_GATT_DISCONNECTING);
        filter.addAction(LeProxy.ACTION_GATT_CONNECTING);
        filter.addAction(LeProxy.ACTION_CONNECT_ERROR);
        filter.addAction(LeProxy.ACTION_CONNECT_TIMEOUT);
        filter.addAction(LeProxy.ACTION_GATT_SERVICES_DISCOVERED);
        filter.addAction(LeProxy.AVAILABLE_DATA);
        return filter;
    }

//    @Override
//    public boolean onCreateOptionsMenu(Menu menu) {
//        getMenuInflater().inflate(R.menu.menu_bar, menu);
//        return super.onCreateOptionsMenu(menu);
//    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        if (item.getItemId() == android.R.id.home) {
            finish();
            return true;
        }

        if (item.getItemId() == R.id.action_update) {
            System.out.println("-------->+我要开始升级了");
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(mLocalReceiver);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(mConnection);
        bleService = null;
        if (timer != null) {
            timer.cancel();
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        spinnerPosition = position;
        etCmd.setText("");
        etCmd.setHint("输入指令");
        switch (position) {
//            case 0: // 设置连接方式
//                header[3] = 0x00;
//                contentData = new byte[]{0x01};
//                header[2] = (byte) contentData.length;
////                sendCMD = byteMerger(header, contentData);
//                break;
            case 0: //蓝牙系统参数配置(预留)
                header[3] = 0x01;
                sendCMD = new byte[]{(byte) 0xAA, (byte) 0xBE, 0x00, 0x72};
                break;
            case 1: //蓝牙系统参数获取(预留)
                header[3] = 0x02;
                break;
//            case 3: //蓝牙通信握手
//                header[3] = 0x03;
//                contentData = new byte[]{(byte) 0xFA, 0x36, (byte) 0xD3, 0x31, (byte) 0xBE, 0x40, 0x27, (byte) 0xE6};
//                header[2] = (byte) contentData.length;
////                sendCMD = byteMerger(header, contentData);
//                break;
            case 2: //开门
                header[3] = 0x04;
//                contentData = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //默认白名单id
                header[2] = 8;
                etCmd.setHint("输入8字节id,需在白名单内");
                break;
            case 3: //设置蓝牙密码
                header[3] = 0x05;
                header[2] = 16;
                etCmd.setHint("输入12字节数据");
                break;
//            case 6: //蓝牙设备复位
//                header[3] = 0x60;
//                contentData = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A}; //8字节 蓝牙用户ID
//                header[2] = (byte) contentData.length;
////                sendCMD = byteMerger(header, contentData);
//                break;
//            case 7: //蓝牙设备擦除
//                header[3] = 0x61;
//                contentData = new byte[]{};
//                header[2] = (byte) contentData.length;
////                sendCMD = byteMerger(header, contentData);
//                break;
//            case 8: //蓝牙设备升级固件(情况不明)
//                header[3] = 0x62;
//                contentData = FileUtil.getBytesFromAssets(this, "R515_test.bin");
////                contentData = new byte[]{};
////                tempCMD[2] = (byte) contentData.length;
////                sendCMD = byteMerger(tempCMD, contentData);
//
//                break;
//            case 9://蓝牙设备升级完成,开始运行
//                header[3] = 0x63;
////                contentData = FileUtil.getFileMD5("R515_test.bin");
//                contentData = FileUtil.getFileMD5(this, "R515_test.bin");
////                String a = TransformUtil.byteArrayToString(contentData);
//                header[2] = 0x10;
////                sendCMD = byteMerger(header, contentData);
//                break;
            case 4: //注册设备信息
                header[3] = 0x70;
                header[2] = 17;
                etCmd.setHint("输入13字节数据,byte0为类型");
                break;
            case 5://注销设备信息
                header[3] = 0x71;
//                contentData = new byte[]{0x02};
                header[2] = 1;
//                sendCMD = byteMerger(header, contentData);
                etCmd.setHint("输入1字节数据(类型)");
                break;
            case 6: //软件版本号
                header[3] = 0x72; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 7: //硬件版本号
                header[3] = 0x73; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 8://设置出厂序列号
                header[3] = 0x74; //命令类型
                contentData = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
                header[2] = (byte) contentData.length;
//                cmd = byteMerger(tempCMD,data);
                etCmd.setHint("输入16字节数据(序列号)");
                break;
            case 9: //获取出厂序列号
                header[3] = 0x75; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 10://更新设备时间,需要更改为当前时间
                header[3] = 0x76; //命令类型
                String now = DateUtil.date2string();
                contentData = TransformUtil.string2bytes(now);
                header[2] = (byte) contentData.length;
                break;
            case 11://获取设备时间
                header[3] = 0x77; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 12://增加黑名单
                header[3] = (byte) 0x80; //命令类型
                etCmd.setHint("输入5或9字节，byte0为类型");
                break;
            case 13://查询黑名单,两个字节,需添加到特殊情况
                header[3] = (byte) 0x81; //命令类型
                etCmd.setHint("输入至少2字节(位置)");
                break;
            case 14://删除黑名单
                header[3] = (byte) 0x82; //命令类型
//                contentData = new byte[]{0x02, 0x00, 0x00, 0x00, 0x00};
//                header[2] = 9;
                etCmd.setHint("输入5或9个字节，byte0为类型");
                break;
            case 15://清空黑名单
                header[3] = (byte) 0x83; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 16://获取黑名单数量
                header[3] = (byte) 0x84; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 17://增加白名单
                header[3] = (byte) 0x85; //命令类型
//                header[2] = 12;
                etCmd.setHint("输入8或12字节,byte0为类型)");
                break;
            case 18://查询白名单
                header[3] = (byte) 0x86; //命令类型

                etCmd.setHint("输入至少2个字节(白名单位置)");
                break;
            case 19://删除白名单
                header[3] = (byte) 0x87; //命令类型
//                header[2] = 9;
                etCmd.setHint("输入5或9个字节数据byte0为类型");
                break;
            case 20://清空白名单
                header[3] = (byte) 0x88; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 21://获取白名单数量
                header[3] = (byte) 0x89; //命令类型
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 22://获取开门次数
                header[3] = (byte) 0x91; //命令类型
                contentData = new byte[]{0x00, 0x00, 0x00, 0x00};
                header[2] = (byte) contentData.length;
                break;
            case 23://批量导出开门记录
                header[3] = (byte) 0x92; //命令类型
                header[2] = 5;
                etCmd.setHint("输入4个字节数据(开门记录位置)");
                break;
            case 24://清空所有开门记录
                header[3] = (byte) 0x93;
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            case 25://读取外部flash(未曾实现)
                header[3] = (byte) 0x94;
                contentData = new byte[]{};
                header[2] = (byte) contentData.length;
                break;
            default:
                break;
        }

//        etCmd.setText(TransformUtil.byteArrayToString(sendCMD));

    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    public void sentByteByCommand() {

        String input = etCmd.getText().toString().trim();
        if (input.length() != 0) {
            if (spinnerPosition == 3) {
                contentData = byteMerger(TransformUtil.string2byteArr(input), new byte[]{(byte) 0xFF, (byte) 0xFF, 0x03, 0x00});
            } else if (spinnerPosition == 23) {
                contentData = byteMerger(new byte[]{0x01}, TransformUtil.string2byteArr(input));
            } else {
                contentData = TransformUtil.string2byteArr(input);
                if (spinnerPosition == 12 || spinnerPosition == 14 || spinnerPosition == 19 || spinnerPosition == 13 || spinnerPosition == 18) {
                    header[2] = (byte) contentData.length;
                }

                if (spinnerPosition == 4) {
                    int type = contentData[0]+1;
                    byte[] tmp = new byte[13];
//                    System.arraycopy(contentData, 0, tmp, 0, 12);

                    contentData = byteMerger(contentData, new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) type, 0});
//                    header[2] = 17;
                }


                if (spinnerPosition==17){
                    if (input.length()==10 || input.length()==18){
                        contentData = byteMerger(TransformUtil.string2byteArr(input),new byte[]{0x19,0x09,0x19});
                    }
                    header[2] = (byte) contentData.length;
                }

            }
        }


        sendCMD = byteMerger(header, contentData);
        bleService.sendCmd(build_cmd(sendCMD));
        if (spinnerPosition == 8) {
            System.out.println(TransformUtil.byteArrayToString(sendCMD));
        }

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_update:
                value_connect = 101; //设备复位
                rlConnect.setVisibility(View.VISIBLE);
                tvConnectStatus.setText("正在复位设备");
                updateDevice();
                break;
            case R.id.btn_send:
                sentByteByCommand();
                break;
            case R.id.btn_clear:
                cmds.clear();
                cmdAdapter.notifyDataSetChanged();
                break;
            case R.id.et_cmd:
                goHexInputActivity();
                break;
        }
    }


    private void updateDevice() { //四个步骤->复位->数据擦除->写固件->运行
        header[3] = 0x60;
        contentData = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //8字节 蓝牙用户ID
        header[2] = (byte) contentData.length;
        sendCMD = byteMerger(header, contentData);
        bleService.sendCmd(build_cmd(sendCMD));
    }

    public byte[] byteMerger(byte[] bt1, byte[] bt2) {
        byte[] bt3 = new byte[bt1.length + bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    private byte[] build_cmd(byte[] bs) {
        int length = bs.length + 1;
        byte[] newCmd = new byte[length];
        newCmd[0] = (byte) 0xAA;
        int count = 0;
        for (int i = 1; i < bs.length; i++) {
            count += bs[i];
            newCmd[i] = bs[i];
        }
        byte a = (byte) count;
        newCmd[bs.length] = a;
        return newCmd;
    }

}
